# app/utils/file_utils.py
import os
import uuid
import re

import docx2txt
import fitz  # PyMuPDF
from typing import List, Optional
from fastapi import UploadFile


def read_file_content(file: UploadFile) -> str:
    """
    读取不同类型文件的内容
    """
    filename = file.filename.lower() if hasattr(file, 'filename') else ""
    content = ""

    try:
        if filename.endswith('.txt'):
            file.file.seek(0)
            content = file.file.read().decode('utf-8')
        elif filename.endswith('.pdf'):
            file.file.seek(0)
            file_bytes = file.file.read()
            pdf_document = fitz.open(stream=file_bytes, filetype="pdf")
            for page_num in range(len(pdf_document)):
                page = pdf_document[page_num]
                content += page.get_text()
        elif filename.endswith((".doc", ".docx")):
            file.file.seek(0)
            file_bytes = file.file.read()
            temp_path = f"/tmp/{uuid.uuid4()}"
            with open(temp_path, "wb") as f:
                f.write(file_bytes)
            content = docx2txt.process(temp_path)
            os.remove(temp_path)
        else:
            raise ValueError(f"Unsupported file format: {filename}")
    except Exception as e:
        content = f"[读取文件出错: {str(e)}]"
    finally:
        # 修复：确保文件指针被重置
        if hasattr(file, 'file') and not file.file.closed:
            file.file.seek(0)

    return content


def split_text(text: str, chunk_size: int = 1000, chunk_overlap: int = 200) -> List[str]:
    """
    将文本分割成指定大小的块，同时保持句子的完整性
    """
    if not text:  # 处理空文本
        return []

    # 使用正则表达式分割文本，优先在句号、问号、感叹号后分割
    sentences = re.split(r'(?<=[。！？.?!])\s*', text)

    chunks = []
    current_chunk = ""

    for sentence in sentences:
        if not sentence.strip():  # 跳过空句子
            continue

        # 如果当前块加上新句子超过了chunk_size，且当前块不为空，则将当前块加入chunks
        if len(current_chunk) + len(sentence) > chunk_size and current_chunk:
            chunks.append(current_chunk.strip())
            # 重叠部分：从上一个块的末尾取chunk_overlap个字符
            overlap = min(len(current_chunk), chunk_overlap)
            current_chunk = current_chunk[-overlap:] + sentence
        else:
            current_chunk += sentence

    # 添加最后一个块
    if current_chunk.strip():
        chunks.append(current_chunk.strip())

    return chunks


def get_file_extension(filename: str) -> str:
    """
    获取文件扩展名
    """
    return os.path.splitext(filename)[1].lower()


def validate_file_extension(filename: str, allowed_extensions: Optional[List[str]] = None) -> bool:
    """
    验证文件扩展名是否在允许的列表中
    """
    if allowed_extensions is None:
        allowed_extensions = ['.txt', '.pdf', '.docx', '.doc']
    ext = get_file_extension(filename)
    return ext in allowed_extensions
